package com.alipay.sofa.award.common.utils;

import com.alibaba.common.lang.StringUtil;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.Random;

/**
 * AwardUtils
 *
 * @author yangguanchao
 * @since 2018/09/03
 */
public class AwardUtils {

    private static final String SOFA_PREFIX = "SOFA";

    private static String       ipAddress   = null;

    private static Random       random      = new Random();

    public static String getInetAddress() {
        if (!StringUtil.isBlank(ipAddress)) {
            return ipAddress;
        }
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress address = null;
            while (interfaces.hasMoreElements()) {
                NetworkInterface ni = interfaces.nextElement();
                Enumeration<InetAddress> addresses = ni.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    address = addresses.nextElement();
                    if (!address.isLoopbackAddress() && address.getHostAddress().indexOf(":") == -1) {
                        ipAddress = address.getHostAddress();
                        return ipAddress;
                    }
                }
            }
            return null;
        } catch (Throwable t) {
            return null;
        }
    }

    public static String getAwardCode() {
        long timestamp = System.currentTimeMillis();
        //ip + time + random
        String ipAddress = getInetAddress();
        long hashCode = FNV64HashCode(ipAddress + timestamp + random.nextInt());
        return SOFA_PREFIX + hashCode;
    }

    /**
     * from http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash
     * @param data String data
     * @return fnv hash code
     */
    public static long FNV64HashCode(String data) {
        //hash FNVHash64 : http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
        long hash = 0xcbf29ce484222325L;
        for (int i = 0; i < data.length(); ++i) {
            char c = data.charAt(i);
            hash ^= c;
            hash *= 0x100000001b3L;
        }
        return hash;
    }
}
